














<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
  <meta name="renderer" content="webkit">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, shrink-to-fit=no", user-scalable=no">
  <title>字节码工具asmtools使用Mamba's Blog</title>
  <link rel="shortcut icon" href="">
  
    
    
      <link rel="stylesheet" href="/css/bootstrap.min.css">
    
      <link rel="stylesheet" href="/css/font-awesome.min.css">
    
      <link rel="stylesheet" href="/css/atom-one-dark.css">
    
      <link rel="stylesheet" href="/css/jquery.fancybox.css">
    
      <link rel="stylesheet" href="/css/nprogress.min.css">
    
      <link rel="stylesheet" href="/css/valine.css">
    
      <link rel="stylesheet" href="/css/life.css">
    
  

  

  <!-- jQuery first, then Tether, then Bootstrap JS. -->
  
  
  
    <script src="/js/jquery-2.2.4.min.js"></script>
  
    <script src="https://cdn1.lncld.net/static/js/3.1.0/av-min.js"></script>
  
    <script src="/js/jquery.pjax.js"></script>
  
    <script src="/js/nprogress.min.js"></script>
  
    <script src="/js/tether.min.js"></script>
  
    <script src="/js/bootstrap.min.js"></script>
  
    <script src="/js/highlight.min.js"></script>
  
    <script src="/js/highlightjs-line-numbers.min.js"></script>
  
    <script src="/js/jquery.fancybox.js"></script>
  
    <script src="/js/jquery.qrcode.min.js"></script>
  
    <script src="/js/Valine.min.js"></script>
  
  
<meta name="generator" content="Hexo 4.2.0"></head>
<body>
<script>AV.init({appId:'',appKey:''});</script>
<script type="text/javascript">
      var config = {
            ClasS: 'Counter',
            el:'.views',
            elP: '.views-post'
      }
</script>
<div class="container">
    <div class="row blog-box-shadow">
        <!--博客主栏开始-->
        <div class="col-xl-9 col-lg-12 blog-main" id="pjax-box">
            <header class="blog-header">
                <a href="http://blackmambaye.gitee.io/blog" class="blog-header-mobile-title">Mamba's Blog</a>
                <a href="javascript:;" class="blog-header-navbar-btn"><i class="fa fa-bars"></i></a>
                <nav class="blog-header-navbar blog-header-fixed">
                    <ul class="blog-navbar-links">
                        
                          <li class="blog-nav-item"><a href="/" class="transition">首页</a></li>
                        
                          <li class="blog-nav-item"><a href="/about/" class="transition">关于</a></li>
                        
                          <li class="blog-nav-item"><a href="/links/" class="transition">链接</a></li>
                        
                        <div class="blog-navbar-right">
                            <form action="">
                                <div class="input-group">
                                    <input type="text" class="blog-header-search" placeholder="search...">
                                    <buttn type="submit" class="blog-header-search-btn"><i class="fa fa-search"></i></buttn>
                                </div>
                            </form>
                        </div>
                    </ul>
                </nav>
            </header>
                
<header class="blog-post-page-title">
    <h4>字节码工具asmtools使用</h4>
    <time datetime="2020-05-09T07:36:00.000Z"><i class="fa fa-clock-o"></i>2020-05-09</time>
    
    
    
    
	
        <span><i class="fa fa-folder-o"></i>
    		
    	       <a href="/blog/categories/JVM/" rel="categories" data-toggle="tooltip" data-placement="top" title="Linux">JVM</a>
    		
        </span>
	
    
</header>
<div class="blog-main-post blog-post-page-box">
    <article class="blog-post-block blog-post-page-content">
        <section>
            
                <h4 id="1-关于asmtools-jar"><a href="#1-关于asmtools-jar" class="headerlink" title="1. 关于asmtools.jar"></a>1. 关于asmtools.jar</h4><p>用途：使得 “.class文件 -&gt; 字节码指令（类似汇编语言）文件 -&gt; .class文件”，并可以修改“字节码指令文件” 改变一个“.class文件”的运行结果。并重新生成class文件</p>
<h4 id="2-获取方式asmtools-jar"><a href="#2-获取方式asmtools-jar" class="headerlink" title="2. 获取方式asmtools.jar"></a>2. 获取方式asmtools.jar</h4><p>环境准备：JDK version 8.0, Ant version 1.8 or later, mercurial</p>
<p>下载：hg clone <a href="http://hg.openjdk.java.net/code-tools/asmtools" target="_blank" rel="noopener">http://hg.openjdk.java.net/code-tools/asmtools</a><br>编译：cd asmtools/build &amp;&amp; ant 上面是下载打包方式，如果图懒省事，直接使用别人打包好的即可：</p>
<h4 id="3-使用案例"><a href="#3-使用案例" class="headerlink" title="3. 使用案例"></a>3. 使用案例</h4><p>以郑雨迪老师在“深入拆解JVM”专栏<a href="https://time.geekbang.org/column/article/11289" target="_blank" rel="noopener">https://time.geekbang.org/column/article/11289</a> 中对boolean类型在jvm中的类型为例示例如何使用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">  <span class="keyword">boolean</span> flag = <span class="keyword">true</span>;</span><br><span class="line">  <span class="keyword">if</span> (flag) System.out.println(<span class="string">"Hello, Java!"</span>);</span><br><span class="line">  <span class="keyword">if</span> (flag == <span class="keyword">true</span>) System.out.println(<span class="string">"Hello, JVM!"</span>);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>javac Foo.java 命令生成 Foo.class 文件， java Foo 命令运行 Foo.class 文件输出结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Hello, Java!</span><br><span class="line">Hello, JVM!</span><br></pre></td></tr></table></figure>

<h6 id="由-class-文件生成-jasm-文件"><a href="#由-class-文件生成-jasm-文件" class="headerlink" title="由 class 文件生成 jasm 文件"></a>由 class 文件生成 jasm 文件</h6><p>如下命令将 class 文件中的内容转换为对应的 jasm 语法</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -jar asmtools.jar jdis Foo.class</span><br></pre></td></tr></table></figure>

<p>执行结果为：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">package  foo;</span><br><span class="line"></span><br><span class="line">super public class Foo</span><br><span class="line">        version 52:0</span><br><span class="line">&#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">public Method &quot;&lt;init&gt;&quot;:&quot;()V&quot;</span><br><span class="line">        stack 1 locals 1</span><br><span class="line">&#123;</span><br><span class="line">                aload_0;</span><br><span class="line">                invokespecial   Method java&#x2F;lang&#x2F;Object.&quot;&lt;init&gt;&quot;:&quot;()V&quot;;</span><br><span class="line">                return;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">public static Method main:&quot;([Ljava&#x2F;lang&#x2F;String;)V&quot;</span><br><span class="line">        stack 2 locals 2</span><br><span class="line">&#123;</span><br><span class="line">                iconst_1;</span><br><span class="line">                istore_1;</span><br><span class="line">                iload_1;</span><br><span class="line">                ifeq    L14;</span><br><span class="line">                getstatic       Field java&#x2F;lang&#x2F;System.out:&quot;Ljava&#x2F;io&#x2F;PrintStream;&quot;;</span><br><span class="line">                ldc     String &quot;Hello, Java!&quot;;</span><br><span class="line">                invokevirtual   Method java&#x2F;io&#x2F;PrintStream.println:&quot;(Ljava&#x2F;lang&#x2F;String;)V&quot;;</span><br><span class="line">        L14:    stack_frame_type append;</span><br><span class="line">                locals_map int;</span><br><span class="line">                iload_1;</span><br><span class="line">                iconst_1;</span><br><span class="line">                if_icmpne       L27;</span><br><span class="line">                getstatic       Field java&#x2F;lang&#x2F;System.out:&quot;Ljava&#x2F;io&#x2F;PrintStream;&quot;;</span><br><span class="line">                ldc     String &quot;Hello, JVM!&quot;;</span><br><span class="line">                invokevirtual   Method java&#x2F;io&#x2F;PrintStream.println:&quot;(Ljava&#x2F;lang&#x2F;String;)V&quot;;</span><br><span class="line">        L27:    stack_frame_type same;</span><br><span class="line">                return;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">&#125; &#x2F;&#x2F; end Class Foo</span><br></pre></td></tr></table></figure>

<p>可以到看到boolean在JVM实际上是作为int处理的<br>iconst_1 将1压入操作数栈<br>istore_1 将操作数栈顶保存至局部变量表1位置，<br>iload_1 再讲局部变量表1 位置加载到操作数栈顶<br>ifeq L14 判断栈顶位置是否为0 为零则跳转到L14</p>
<p>我们来尝试修改 将压入的1 改为2 看看什么效果<br>linux下java -jar asmtools.jar jdis Foo.class &gt; Foo.jasm将上述结果输出到文件中。window下直接新建文件将上一个命令输出结果内容拷贝过去即可<br>将 Foo.class 中的 int i = 1; 修改成 int i = 2;，我们只需要替换 Foo.jasm 文件中的 iconst_1 为 iconst_2</p>
<h6 id="由jsam文件生成class文件"><a href="#由jsam文件生成class文件" class="headerlink" title="由jsam文件生成class文件"></a>由jsam文件生成class文件</h6><p>将修改过后的Foo.jasm 执行命令生成class文件</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -jar asmtools.jar jasm Foo.jasm</span><br></pre></td></tr></table></figure>

<p>此时再执行 java Foo 输出：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Hello, Java!</span><br></pre></td></tr></table></figure>

<p>可见字节码已经被修改，至于为何第一个位false第二个为true，解释为：<br>ifeq 指令的逻辑是 判断栈顶元素是否为0 不为零纪委true了所以改为2 依然为true。<br>if_cmpne做整数比较，iconst_1是否等于flag（1）比较失败。</p>
<h6 id="扩展"><a href="#扩展" class="headerlink" title="扩展"></a>扩展</h6><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span>&#123;  </span><br><span class="line">	<span class="keyword">static</span> <span class="keyword">boolean</span> boolValue;  </span><br><span class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;    </span><br><span class="line">		boolValue = <span class="keyword">true</span>; <span class="comment">// 将这个true替换为2或者3，再看看打印结果   </span></span><br><span class="line">		<span class="keyword">if</span> (boolValue) System.out.println(<span class="string">"Hello, Java!"</span>);    </span><br><span class="line">		<span class="keyword">if</span> (boolValue == <span class="keyword">true</span>) System.out.println(<span class="string">"Hello, JVM!"</span>); </span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果：<br>当替换为2的时候无输出<br>当替换为3的时候打印HelloJava及HelloJVM<br>是因为将boolean 保存在静态域中,指定了其类型为’Z’,当修改为2时取低位最后一位为0,当修改为3时取低位最后一位为1<br>则说明boolean的掩码处理是取低位的最后一位</p>
<h4 id="4-总结"><a href="#4-总结" class="headerlink" title="4.总结"></a>4.总结</h4><p>主要就两条命令 由 class 文件生成 jasm 文件：java -jar asmtools.jar jdis Foo.class &gt; Foo.jasm<br>由 jasm 文件生成 class 文件：java -jar asmtools.jar jasm Foo.jasm</p>

            
        </section>
        <footer class="blog-post-page-tags">
        
			
				
			<a href="/blog/tags/asmtool/" rel="tag" data-toggle="tooltip" data-placement="top" title="Linux">asmtool</a>
				
			
		
        </footer>
    </article>
    <article class="blog-post-page-readmore">
    	
    	
		

		
		

        <div style="clear: both;"></div>
    </article>

    <article class="blog-post-block blog-post-page-content">
            <div class="row">
            
                <div class="col-md-4 col-sm-4 post-page-more-btn">
                    <span class="post-comments-btn btn btn-info btn-block" data-toggle="tooltip" data-placement="top" title="本站采用Disqus评论组件，若您没有科学上网可能会无法查看并评论">加载评论</span>
                </div>
            
                <div class="col-md-4 col-sm-4 post-page-more-btn">
                    <span  data-toggle="modal" data-target="#post-donate-content">
                        <span id="post-donate-btn" class="btn btn-danger btn-block" data-toggle="tooltip" data-placement="top" title="如果您觉得本文还不错或者对您有帮助，可以考虑打赏一下作者哦">打赏本文</span>
                    </span>
                </div>
                <div class="col-md-4 col-sm-4 post-page-more-btn">
                    <span  data-toggle="modal" data-target="#post-qrcode-content">
                        <span><span id="post-qrcode-btn" class="btn btn-success btn-block" data-toggle="tooltip" data-placement="top" title="微信扫描二维码手机端查看本文及分享本文">二维码</span></span>
                    </span>
                </div>
            </div>
        <div class="post-more-function-br"></div>

        <div class="modal fade" id="post-donate-content" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">打赏本文</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="row post-donate-content">
                            <div class="col-md-4">
                                <p>支付宝</p>
                                <img class="post-donate-content-img no-lightbox" src="http://dl.weic96.cn/logo.png"/>
                            </div>
                            <div class="col-md-4">
                                <p>微信</p>
                                <img class="post-donate-content-img no-lightbox" src="http://dl.weic96.cn/logo.png"/>
                            </div>
                            <div class="col-md-4">
                                <p>财付通</p>
                                <img class="post-donate-content-img no-lightbox" src="http://dl.weic96.cn/logo.png"/>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="modal fade" id="post-qrcode-content" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-sm" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">文章二维码</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <div class="row post-qrcode-content">
                            <span class="post-qrcode-content-canvas"></span>
                            <img class="post-qrcode-content-img no-lightbox" src=""/>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                    </div>
                </div>
            </div>
        </div>
        
        <script>
            // post QRcode
            // 中文转码
            function toUtf8(str) {
                var out, i, len, c;
                out = "";
                len = str.length;
                for (i = 0; i < len; i++) {
                    c = str.charCodeAt(i);
                    if ((c >= 0x0001) && (c <= 0x007F)) {
                        out += str.charAt(i);
                    } else if (c > 0x07FF) {
                        out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
                        out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
                        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
                    } else {
                        out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
                        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
                    }
                }
                return out;
            }
            // 生成
            var qrcode= $('.post-qrcode-content-canvas').qrcode({width: 150,height: 150,text: toUtf8("http://blackmambaye.gitee.io/blog/2020/05/09/%E5%AD%97%E8%8A%82%E7%A0%81%E5%B7%A5%E5%85%B7asmtools%E4%BD%BF%E7%94%A8/")}).hide();
            var canvas=qrcode.find('canvas').get(0);
            $('.post-qrcode-content-img').attr('src',canvas.toDataURL('image/jpg'));
        </script>

        
    </article>
    
</div>

                
            <footer class="blog-footer">
                <p class="blog-footer-left">Copyright ©  2020 <a href="http://blackmambaye.gitee.io/blog">Mamba's Blog</a></p>
                <p class="blog-footer-right">Powered by <a href="https://hexo.io" target="_blank">Hexo</a>,Theme <a href="https://note.isweic.com/themes-life/" target="_blank">Life</a></p>
            </footer>
        </div><!--博客主栏结束-->
        <!--博客侧边栏开始-->
        <div class="col-xl-3 blog-sidebar">
            <div class="blog-sidebar-title">
                <a href="">Mamba's Blog</a>
            </div>
            <div class="blog-sidebar-logo">
                <img src="http://dl.weic96.cn/logo.png">
            </div>
            <div class="blog-sidebar-count blog-sidebar-padding">
                <div class="blog-sidebar-count-left">
                    <p class="blog-sidebar-count-p">1</p>
                    <span class="blog-sidebar-count-span">文章</span>
                </div>
                <div class="blog-sidebar-count-right">
                    <p class="blog-sidebar-count-p">1</p>
                    <span class="blog-sidebar-count-span">标签</span>
                </div>
                <div style="clear: both;"></div>
            </div>
            <div class="blog-sidebar-icon blog-sidebar-padding">
                <ul>
                    <li><a href="" class="icon-github" target="_blank" data-toggle="tooltip" data-placement="top" title="Github"><i class="fa fa-github"></i></a></li>
                    <li><a href="" class="icon-weibo" target="_blank" data-toggle="tooltip" data-placement="top" title="新浪微博"><i class="fa fa-weibo"></i></a></li>
                    <li><a href="" class="icon-twitter" target="_blank" data-toggle="tooltip" data-placement="top" title="Twitter"><i class="fa fa-twitter"></i></a></li>
                    <!--<li><a href="" class="icon-facebook" target="_blank" data-toggle="tooltip" data-placement="top" title="FaceBook"><i class="fa fa-facebook"></i></a></li>-->
                    <li><a href="mailto:" class="icon-email" data-toggle="tooltip" data-placement="top" title="E-Mail"><i class="fa fa-envelope"></i></a></li>
                    <li><a href="" class="icon-rss" data-toggle="tooltip" target="_blank" data-placement="top" title="RSS"><i class="fa fa-rss"></i></a></li>
                </ul>
            </div>
            <div class="blog-sidebar-categories">
                <h4 class="blog-sidebar-h4"><i class="fa fa-folder-open"></i>&nbsp;文章分类</h4>
                <ul class="list-group blog-sidebar-padding">
                  
                    
                      <li class="list-group-item justify-content-between">
                          <a href="/blog/categories/JVM/">JVM</a>
                          <span class="badge badge-default badge-pill">1</span>
                      </li>
                    
                  
                </ul>
            </div>
            <div class="blog-sidebar-tags">
                <h4 class="blog-sidebar-h4"><i class="fa fa-tag"></i>&nbsp;标签云</h4>
                <ul class="blog-sidebar-tags-ul blog-sidebar-padding">
                  
                    
                      <li><a href="/blog/tags/asmtool/" class="tag-could" data-toggle="tooltip" data-placement="top" title="asmtool">asmtool</a></li>
                    
                  
                </ul>
            </div>
            <script>
              // 博客侧栏标签云随机色
              var tag_cloud = $('.tag-could');
              tag_cloud.each(function () {
                  var Cnum = 9;
                  var Crand = parseInt(Math.random() * Cnum);
                  $(this).addClass("tag-could" + Crand);
              })
            </script>
            <!--返回顶部按钮-->
            <div class="retop">
                <i class="fa fa-angle-up"></i>
            </div>
        </div><!--博客侧边栏结束-->
    </div>
</div>
<script src="/js/LeanStatistics.min.js"></script>
<script src="/js/Life.js"></script>
<script type="text/javascript">
    hljs.initHighlightingOnLoad();
    hljs.initLineNumbersOnLoad();
    otherF();
    LeanStatistics();
    $(document).pjax('a', '#pjax-box', {fragment:'#pjax-box', timeout:8000}).on('pjax:complete', function() {
      $('pre code').each(function(i, block){
        hljs.highlightBlock(block);
      })
      $('code.hljs').each(function(i, block) {
        hljs.lineNumbersBlock(block);
      });
      LeanStatistics();
    }).on('pjax:start', function() { NProgress.start(); }).on('pjax:end',   function() {
      NProgress.done();
      otherF();
    });
</script>
</body>
</html>
